#pragma once 

#include "base.h" //for Slice 

namespace helper {
namespace demo {

template<typename T>
class Cast {
public:
  using cast_type = T;

  explicit Cast(const std::string & name) : name_(name) {}
  ~Cast(){}

  Slice toSlice(const cast_type & t) const{
    return Slice((char*)&t, sizeof(t));
  }

  cast_type & fromSlice__(const Slice & slice) const{
    assert(slice.size() >= sizeof(cast_type));
    return *(reinterpret_cast<cast_type*>(const_cast<char*>(slice.data())));
  }
  std::pair<bool, cast_type &> fromSlice(const Slice & slice) const{
    if(slice.size() >= sizeof(cast_type)){
      return std::pair<bool, cast_type&>(true, *(reinterpret_cast<cast_type*>(const_cast<char*>(slice.data()))));
    }
    return std::pair<bool, cast_type&>(false, null);
  }

  int compare(const Slice & left, const Slice & right) const {
    if(left.size() >= sizeof(cast_type) && right.size() >= sizeof(cast_type)){
        return fromSlice__(left) - fromSlice__(right);
    }
    return left.size() - right.size();
  }
  const std::string & name() const { return name_; }

private:
  static cast_type null;
  std::string name_;

};
template<typename T> typename Cast<T>::cast_type Cast<T>::null;

} //namespace demo
} //namespace helper
